﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System;

//公式解析的部分
using Expression.api;
using Expression.impl;

using Motion.MotionPlatform;
using Motion.MotionPlatform.Tools;
using System.IO;

public class VariableManager
{

	//公式解析——变量,不包含公式
	public static List<string> _varList = new List<string>();

	//变量，变量小数点位数
	public static Dictionary<string, int> _varDecimalPlaces = new Dictionary<string, int>();

	//当前运行行的Triiger列中在教的时候运行的表格。
	public static string triggerTeachingContent = "";

	//将float值转化成固定小数点位数的float
	static float getDecimalPlacesStr(float str, int tmpInt)
	{
		if (tmpInt == 0)
		{
			return ((int)str);
		}
		else if (tmpInt == 1)
		{
			return float.Parse(str.ToString("0.0"));
		}
		else if (tmpInt == 2)
		{
			return float.Parse(str.ToString("0.00"));
		}
		else if (tmpInt == 3)
		{
			return float.Parse(str.ToString("0.000"));
		}
		else if (tmpInt == 4)
		{
			return float.Parse(str.ToString("0.0000"));
		}
		else if (tmpInt == 5)
		{
			return float.Parse(str.ToString("0.00000"));
		}
		else if (tmpInt == 6)
		{
			return float.Parse(str.ToString("0.000000"));
		}
		else if (tmpInt == 7)
		{
			return float.Parse(str.ToString("0.0000000"));
		}

		return str;
	}

	/// <summary>
	/// 取值
	/// </summary>
	/// <param name="ID"></param>
	/// <returns></returns>
	public static object GetValue(string ID)
	{
		// 该名字是否已创建变量或表达式；
		if (ExpressionManager.IsCreated(ID))
		{
			float tmpValue = 0;
			string tmpStr = ExpressionManager.GetValue(ID).ToString();


			//float值
			if (ExpressionManager.GetCurrentType(ID) == typeof(float) || ExpressionManager.GetCurrentType(ID) == typeof(double))
			{
				if (float.TryParse(tmpStr, out tmpValue))
				{
					tmpValue = getDecimalPlacesStr(tmpValue, _varDecimalPlaces[ID]);
					return tmpValue;
				}
				else
				{
					Debug.LogError("参数表中ID为" + ID + "的变量的值有问题");
					return -1f;
				}
			}
			//string值
			else if (ExpressionManager.GetCurrentType(ID) == typeof(string))
			{
				return ExpressionManager.GetValue(ID).ToString();
			}
			else
			{
				return ExpressionManager.GetValue(ID).ToString();
			}
		}
		else
		{
			Debug.LogError("参数表中不存在ID为" + ID + "的变量或公式");
			return -1f;
		}
	}

	/// <summary>
	/// 根据运动表格里面的参数获得参数表里面相应的变量值
	/// </summary>
	/// <param name="tmpStr"></param>
	/// <returns></returns>
	public static string GetExcelVarValue(string tmpStr, List<string> data_row, string motion_symbol, DataTable group_table)
	{

		string str = tmpStr.Substring(1);
		string tmpReturnValue = "";
		if(str.Contains("$")){
			string[] tmpStrs = str.Split('$');
			str = tmpStrs[0];

			if (ExpressionManager.IsCreatedVariable(tmpStrs[1]))
			{
				tmpReturnValue = "$" + tmpStrs[1];
			}
			else {
				Debug.LogError(Motion.MotionPlatform.MotionPlatformData.excelName + "的表格行EXCEL@" + data_row[1]  + "中的变量" + tmpStrs[1] + "在公式表中不存在");
			}
		}
		// 该名字是否已创建变量或表达式；
		if (ExpressionManager.IsCreated(str))
		{
			//该变量是否是随机变量
			if (ExpressionManager.IsCreatedExpression(str) && ExpressionManager.GetExpression(str).ToString().Contains("RANDOM") && (!Motion_Data.IsVarProcess) && Motion_Data.isEditor)
			{
				ProcessRandomVar(str, data_row, motion_symbol, group_table, tmpReturnValue);
			}

			//如果该变量是输入变量，或者被输入变量影响的变量
			if (Motion_Data.isEditor && (!Motion_Data.IsVarProcess))
			{
				//是否被输入变量影响
				bool isInputVarRelated = false;
				//输入变量在变量表里面的索引
				int indexInputVar = 0; 

				//检查当前表格是否被输入变量影响
				//for (int i = 0; i < CheckVar._SpecialVars.Count; i++)
				for (int i = CheckVar._SpecialVars.Count - 1; i >= 0; i--)
				{
					if (CheckVar._SpecialVars[i].ExcelContent.StartsWith("PANEL"))
					{
						//是否是输入变量
						if (CheckVar._SpecialVars[i].VarID == str) 
						{
							isInputVarRelated = true;
							indexInputVar = i;
							break;
						}

						if (CheckVar._SpecialVars[i].relatedExps.Contains(str))
						{
							isInputVarRelated = true;
							indexInputVar = i;
							break;
						}
					}
				}

				//如果当前运动被输入变量影响
				if (isInputVarRelated)
				{
					ProcessInputVar(str, data_row, motion_symbol, group_table, tmpReturnValue, indexInputVar);
				}
			}

			object tmpObject = VariableManager.GetValue(str);
			if (CheckVar._ChangedVars.ContainsKey(str))
			{
				//如果在处理跳转时的随机变量和输入变量,用记录的值替换掉随机值和输入变量
				if (Motion_Data.IsVarProcess)
				{
					//tmpObject = CheckVar._ChangedVars[str];

					//一个变量可能出现多次，不同行出现的同一变量可能有不同值
					Dictionary<string, object> tmpDic = CheckVar._AllChangedVars[str];
					List<string> tmpListVar = new List<string>(tmpDic.Keys);

					//当前文件名
					int currentTable = 1;
					//当前行
					int currentRow = 2;

					for (int i = 0; i < tmpListVar.Count; i++ )
					{
						string[] tmpStrssss = tmpListVar[i].Split('_');

						//文件名
						int varTable = int.Parse(tmpStrssss[0].Substring(1));
						//文件行
						int varRow = int.Parse(tmpStrssss[1]);

						
						if (Motion_Data.VarProcessTable > varTable || (Motion_Data.VarProcessTable == varTable && Motion_Data.VarProcessRow > varRow))
						{
							if (varTable > currentTable || (varTable == currentTable && varRow > currentRow))
							{
								currentTable = varTable;
								currentRow = varRow;
								tmpObject = tmpDic[tmpListVar[i]];
							}
						}
					}

				}
				//正常运行:输入变量也要改变成用记录的值
				else if (!Motion_Data.IsVarProcess && (ExpressionManager.IsCreatedVariable(str) || (ExpressionManager.IsCreatedExpression(str) && !ExpressionManager.GetExpression(str).ToString().Contains("RANDOM"))))
				{
					tmpObject = CheckVar._ChangedVars[str];

					//Dictionary<string, object> tmpDic = CheckVar._AllChangedVars[str];
					//List<string> tmpListVar = new List<string>(tmpDic.Keys);

					////当前文件名
					//int currentTable = 1;
					////当前行
					//int currentRow = 2;

					//for (int i = 0; i < tmpListVar.Count; i++)
					//{
					//    string[] tmpStrssss = tmpListVar[i].Split('_');

					//    //文件名
					//    int varTable = int.Parse(tmpStrssss[0].Substring(1));
					//    //文件行
					//    int varRow = int.Parse(tmpStrssss[1]);


					//    if (int.Parse(Motion.MotionPlatform.MotionPlatformData.excelName.Substring(1)) > varTable || (int.Parse(Motion.MotionPlatform.MotionPlatformData.excelName.Substring(1)) == varTable && (Motion.MotionPlatform.MotionPlatformData.mainRowNumber + 2) > varRow))
					//    {
					//        if (varTable > currentTable || (varTable == currentTable && varRow > currentRow))
					//        {
					//            currentTable = varTable;
					//            currentRow = varRow;
					//            tmpObject = tmpDic[tmpListVar[i]];
					//        }
					//    }
					//}
				}
			}
	
			//该变量是否是随机变量，记录修改过的随机变量
			if (ExpressionManager.IsCreatedExpression(str) && ExpressionManager.GetExpression(str).ToString().Contains("RANDOM") && (!Motion_Data.IsVarProcess))
			{
				string tmpExcelName = Motion.MotionPlatform.MotionPlatformData.excelName;
				int tmpExcelRow = (Motion.MotionPlatform.MotionPlatformData.mainRowNumber + 2);

				if (!CheckVar._AllChangedVars.ContainsKey(str))
				{
					Dictionary<string, object> tmpDic = new Dictionary<string, object>();
					tmpDic.Add(tmpExcelName + "_" + (tmpExcelRow), tmpObject);
					CheckVar._AllChangedVars.Add(str, tmpDic);
				}
				else
				{
					if (!CheckVar._AllChangedVars[str].ContainsKey(tmpExcelName + "_" + (tmpExcelRow)))
					{
						CheckVar._AllChangedVars[str].Add(tmpExcelName + "_" + (tmpExcelRow), tmpObject);
					}
					else
					{
						CheckVar._AllChangedVars[str][tmpExcelName + "_" + (tmpExcelRow)] = tmpObject;
					}
				}

				if (!CheckVar._ChangedVars.ContainsKey(str))
				{
					CheckVar._ChangedVars.Add(str, tmpObject);
				}
				else {
					CheckVar._ChangedVars[str] = tmpObject;
				}

				
			}

			return tmpObject.ToString() + tmpReturnValue;
		}
		else
		{
			Debug.LogError("参数表中不存在ID为" + str + "的变量或公式");
			return "";
		}
	}

	/// <summary>
	/// 随机变量处理
	/// </summary>
	/// <param name="motion_symbol"></param>
	/// <param name="str"></param>
	static void ProcessRandomVar(string str, List<string> data_row, string motion_symbol, DataTable group_table, string tmpReturnValue)
	{
		Debug.Log("出现随机变量:" + str + "," + Motion.MotionPlatform.MotionPlatformData.excelName + "," + Motion.MotionPlatform.MotionPlatformData.mainRowNumber);

		//记录随机变量，该随机变量出现的表格名，行数
		SpecialVar tmpSpecialVar = new SpecialVar();
		tmpSpecialVar.VarID = str;
		tmpSpecialVar.ExcelName = Motion.MotionPlatform.MotionPlatformData.excelName;
		tmpSpecialVar.ExcelRow = (Motion.MotionPlatform.MotionPlatformData.mainRowNumber + 2);

		bool isRight = true;
		//检查影响到的物体
		if (motion_symbol == "EXCEL")
		{
			tmpSpecialVar.ExcelContent = "EXCEL@" + data_row[1];

			List<Transform> listTrans = new List<Transform>();

			//Group Column
			int groupColumn = Motion.MotionPlatform.Motion_Compute.IntConversion(data_row[2], ref isRight) + 1;
			//运动物体信息
			string objName = "";
			objName = (string)group_table.Rows[0][groupColumn].ToString();
			if (!tmpSpecialVar.relatedObj.Contains(objName))
			{
				//tmpSpecialVar.relatedObj.Add(objName);
				GameObject tmpObj = GameObject.Find(objName);
				if (tmpObj == null)
				{
					Debug.LogError(Motion.MotionPlatform.MotionPlatformData.excelName + "文件中Group" + data_row[2] + "物体组中" + objName + "物体在场景中不存在");
				}
				TransformRecursion(tmpObj.transform, tmpSpecialVar.relatedObj);
				//TODO_ERROR:GameObject.Find检查

				listTrans.Add(GameObject.Find(objName).transform);
			}
			for (int i = 1; i < group_table.Rows.Count; i++)
			{
				objName = (string)group_table.Rows[i][groupColumn].ToString();
				if (objName == "")
					break;

				GameObject tmpObj = GameObject.Find(objName);
				if (tmpObj == null)
				{
					Debug.LogError(Motion.MotionPlatform.MotionPlatformData.excelName + "文件中Group" + data_row[2] + "物体组中" + objName + "物体在场景中不存在");
				}
				listTrans.Add(tmpObj.transform);
				if (!tmpSpecialVar.relatedObj.Contains(objName))
				{
					//tmpSpecialVar.relatedObj.Add(objName);
					TransformRecursion(tmpObj.transform, tmpSpecialVar.relatedObj);
				}
			}

			//记录位置信息
			Debug.Log("记录位置信息:" + tmpSpecialVar.ExcelName + "_" + tmpSpecialVar.ExcelRow);
			Positions.recordLocations(tmpSpecialVar.ExcelName + "_" + tmpSpecialVar.ExcelRow + "_" + tmpSpecialVar.ExcelContent, "C", listTrans);
			//TODO:记录状态以便还原
			if (tmpReturnValue != "")
			{
				//记录公式表里面的参数
				Variables.recordVars(tmpSpecialVar.ExcelName + "_" + tmpSpecialVar.ExcelRow, tmpReturnValue.Substring(1));
			}

			//如果当前运动时处在教的模式下，并且是Trigger列里面的EXCEL
			if (triggerTeachingContent.Contains(tmpSpecialVar.ExcelContent))
			{
				//记录触发对应的随机变量
				Variables.recordVars("Trigger_" + tmpSpecialVar.ExcelName + "_" + tmpSpecialVar.ExcelRow, tmpSpecialVar.VarID);
			}
		}

		//检查影响到的公式
		tmpSpecialVar.relatedExps = ExpressionManager.AssociatedExpression(tmpSpecialVar.VarID);

		CheckVar._SpecialVars.Add(tmpSpecialVar);
	}

	/// <summary>
	/// 输入变量处理
	/// </summary>
	static void ProcessInputVar(string str, List<string> data_row, string motion_symbol, DataTable group_table, string tmpReturnValue, int indexInputVar)
	{ 
		Debug.Log("出现输入变量或输入变量所影响到的变量:" + str + "," + Motion.MotionPlatform.MotionPlatformData.excelName + "," + Motion.MotionPlatform.MotionPlatformData.mainRowNumber);

		bool isRight = true;
		//检查影响到的物体
		if (motion_symbol == "EXCEL")
		{
			//记录输入变量的影响表格行
			string tmpExcel = Motion.MotionPlatform.MotionPlatformData.excelName;
			int tmpRow = (Motion.MotionPlatform.MotionPlatformData.mainRowNumber + 2);
			string tmpRelatedExcel = tmpExcel + "_" + tmpRow + "_" + "EXCEL@" + data_row[1];
			if (!CheckVar._SpecialVars[indexInputVar].relatedExcel.Contains(tmpRelatedExcel))
			{
				CheckVar._SpecialVars[indexInputVar].relatedExcel.Add(tmpRelatedExcel);
			}

			//记录输入变量的影响物体
			List<Transform> listTrans = new List<Transform>();
			//Group Column
			int groupColumn = Motion.MotionPlatform.Motion_Compute.IntConversion(data_row[2], ref isRight) + 1;
			//运动物体信息
			string objName = "";
			objName = (string)group_table.Rows[0][groupColumn].ToString();
			GameObject tmpObj = GameObject.Find(objName);
			if (tmpObj == null)
			{
				Debug.LogError(Motion.MotionPlatform.MotionPlatformData.excelName + "文件中Group" + data_row[2] + "物体组中" + objName + "物体在场景中不存在");
			}
			listTrans.Add(GameObject.Find(objName).transform);
			if (!CheckVar._SpecialVars[indexInputVar].relatedObj.Contains(objName))
			{
							
				TransformRecursion(tmpObj.transform, CheckVar._SpecialVars[indexInputVar].relatedObj);
				//TODO_ERROR:GameObject.Find检查
			}
			for (int i = 1; i < group_table.Rows.Count; i++)
			{
				objName = (string)group_table.Rows[i][groupColumn].ToString();
				if (objName == "")
					break;

				tmpObj = GameObject.Find(objName);
				if (tmpObj == null)
				{
					Debug.LogError(Motion.MotionPlatform.MotionPlatformData.excelName + "文件中Group" + data_row[2] + "物体组中" + objName + "物体在场景中不存在");
				}
							
				listTrans.Add(tmpObj.transform);
				if (!CheckVar._SpecialVars[indexInputVar].relatedObj.Contains(objName))
				{
					TransformRecursion(tmpObj.transform, CheckVar._SpecialVars[indexInputVar].relatedObj);
				}
			}

			//记录位置信息
			Positions.recordLocations(CheckVar._SpecialVars[indexInputVar].ExcelName + "_" + CheckVar._SpecialVars[indexInputVar].ExcelRow + "_" + CheckVar._SpecialVars[indexInputVar].ExcelContent, "C", listTrans);
			//TODO:记录状态以便还原
			if (tmpReturnValue != "")
			{
				//记录公式表里面的参数
				Variables.recordVars(CheckVar._SpecialVars[indexInputVar].ExcelName + "_" + CheckVar._SpecialVars[indexInputVar].ExcelRow, tmpReturnValue.Substring(1));
			}
		}
	}

	//遍历搜寻子物体；
	public static void TransformRecursion(Transform aimTrans, List<string> al)
	{
		if (!al.Contains(aimTrans.gameObject.name))
		{
			al.Add(aimTrans.gameObject.name);
		}
		if (aimTrans.childCount > 0)
		{
			foreach (Transform child in aimTrans)
			{
				TransformRecursion(child, al);
			}
		}
	}


	/// <summary>
	/// 设置值
	/// </summary>
	/// <param name="ID"></param>
	/// <param name="f"></param>
	public static void SetValue(string ID, object f, bool changeRelated)
	{
		if (ExpressionManager.IsCreatedVariable(ID))
		{
			ExpressionManager.ChangeValue(ID, f);
		}
		else
		{
			Debug.LogError("参数表中不存在ID为" + ID + "的变量");
		}
	}
}

public class Variables {

	

	/// <summary>
	/// 保存Variable变量值
	/// </summary>
	/// <param name="str">表名：excel名+row行数(C1_6)</param>
	/// <param name="tmpVar">变量名</param>
	public static void recordVars(string str, string tmpVar)
	{
		//位置信息路径
		string locationPath = MotionPlatformData.taskRootPath + MotionPlatformData.taskName + "/";

		//检验根目录是否存在
		if (Directory.Exists(locationPath))
		{

			JsonOperator jsonOp = new JsonOperator();
			string[] nameArray = new string[] { "VARNAME", "VARVALUE" };
			string[,] contentArray = new string[2, 1];

			contentArray[0, 0] = tmpVar;
			contentArray[1, 0] = VariableManager.GetValue(tmpVar).ToString();

			jsonOp.JsonWriter(locationPath + "C/tmpVariable.json", str, nameArray, contentArray, false);
		}
	}

	
	/// <summary>
	/// 获得Trigger对应的随机变量
	/// </summary>
	/// <param name="str"></param>
	/// <returns></returns>
	public static string getTriggerRelatedVar(string str) {

		string tmpVar = "";

		JsonOperator jsonOp = new JsonOperator();
		//位置信息路径
		string locationPath = MotionPlatformData.taskRootPath + MotionPlatformData.taskName + "/";

		if (!File.Exists(locationPath + "C/" + "tmpVariable.json"))
		{
			Debug.LogError(locationPath + "C/" + "tmpVariable.json文件不存在");
			return tmpVar;
		}

		DataTable dt = jsonOp.JsonReader(locationPath + "C/" + "tmpVariable.json", str);
		if (dt == null)
		{
			Debug.LogWarning(locationPath + "C/" + "tmpVariable.json文件中不存在" + str);
			return tmpVar;
		}

		tmpVar = dt.Rows[0][0].ToString();

		return tmpVar;
	}

	/// <summary>
	/// 设置Variable变量值
	/// </summary>
	/// <param name="str">表名：excel名+row行数(C1_6)</param>
	public static void setVars(string str)
	{
		JsonOperator jsonOp = new JsonOperator();
		//位置信息路径
		string locationPath = MotionPlatformData.taskRootPath + MotionPlatformData.taskName + "/";

		if (!File.Exists(locationPath + "C/" + "tmpVariable.json"))
		{
			Debug.LogError(locationPath + "C/" + "tmpVariable.json文件不存在");
			return;
		}

		DataTable dt = jsonOp.JsonReader(locationPath + "C/" + "tmpVariable.json", str);
		if (dt == null)
		{
			Debug.LogWarning(locationPath + "C/" + "tmpVariable.json文件中不存在" + str);
			return;
		}

		for (int i = 0; i < dt.Rows.Count; i++)
		{
			DataRow dr = dt.Rows[i];

			string tmpVar = dr[0].ToString();
			object tmpValue = dr[1];

			VariableManager.SetValue(tmpVar, tmpValue, false);
		}
	}
}